<template>
  <el-cascader
    ref="myCascader"
    :model-value="modelValue"
    :options="deptOptions"
    :props="configMerge.cascaderProps"
    :placeholder="configMerge.placeholder"
    :clearable="configMerge.clearable"
    :separator="configMerge.separator"
    :show-all-levels="configMerge.showAllLevels"
    :collapse-tags="configMerge.collapseTags"
    style="width: 100%"
    @change="handleSelect"
    @close="handelColse"
  />
</template>

<script lang="ts" setup>
  import { ref, onMounted, computed, watch } from 'vue'
  import { flatListToTree } from '@/utils/flatListToTree'
  import { mergeConfig } from '@/utils/configMerge'
  import { params } from '@/types/common'
  import { postFetch } from '@/api/common'
  defineOptions({ name: 'Cascader' })
  const myCascader = ref()
  // 默认配置
  const defaultCascaderProps = {
    placeholder: '请选择',
    clearable: true,
    disabled: false,
    size: 'default',
    showAllLevels: true,
    separator: ' - ',
    collapseTags: false,
    cascaderProps: {
      value: 'id',
      label: 'name',
      expandTrigger: 'click' as 'click' | 'hover',
      emitPath: false,
      checkStrictly: true,
      multiple: false,
    },
  }

  interface Props {
    modelValue?: string | string[] | null
    config?: Record<string, any>
    excludeId?: string | string[]
    placeholder?: string
    listQuery?: {
      url: string
      params?: params
    }
  }

  const props = withDefaults(defineProps<Props>(), {
    modelValue: null,
    config: () => ({}),
    excludeId: null,
    placeholder: undefined,
    listQuery: () => ({
      url: '/department/getAll',
      params: {},
    }),
  })
  // watch(
  //   () => props.modelValue,
  //   (newVal) => {
  //     console.log('选中的部门ID:', newVal)
  //   },
  // )
  // Emits
  const emit = defineEmits<{
    'update:modelValue': [value: string[] | string | null]
    change: [value: string[] | string | null]
    select: [deptId: string[] | string | null, deptInfo: any | null]
  }>()
  // Reactive data
  const deptOptions = ref([])
  // Computed
  const configMerge = computed(() => {
    // 如果直接传递了 placeholder prop，优先使用它
    const finalConfig = mergeConfig(defaultCascaderProps, props.config || {})
    if (props.placeholder !== undefined) {
      finalConfig.placeholder = props.placeholder
    }
    return finalConfig
  })
  // 判断对象数组的每一项是否含有指定字段
  const dataType = (data: object[], value: string) => {
    return data.some((item) => Object.prototype.hasOwnProperty.call(item, value))
  }
  // Methods
  /** 获取部门列表数据 */
  const getDeptList = async () => {
    // const temp = await getDeptListAllService()
    postFetch(props.listQuery.url, props.listQuery.params).then((res) => {
      // 如果需要排除某个部门（编辑时排除自己）
      let filteredTemp = res
      if (props.excludeId) {
        const excludeIds = Array.isArray(props.excludeId) ? props.excludeId : [props.excludeId]
        filteredTemp = res.filter((item) => !excludeIds.includes(item.id.toString()))
      }
      deptOptions.value = dataType(filteredTemp, 'children') ? filteredTemp : flatListToTree(filteredTemp)
    })
  }
  /** 处理选择事件 */
  const handleSelect = (value: string[] | string | null) => {
    emit('update:modelValue', value)
    // 递归查找选中的部门信息
    const findById = (depts: any[], targetId: string): any => {
      for (const dept of depts) {
        // 确保类型匹配，都转换为字符串进行比较
        if (dept.id.toString() === targetId) {
          return dept
        }
        if (dept.children && dept.children.length > 0) {
          const found = findById(dept.children, targetId)
          if (found) return found
        }
      }
      return null
    }

    // 获取选中的部门信息
    let selectedDept = null
    if (value) {
      if (Array.isArray(value) && value.length > 0) {
        // 如果是数组，查找所有选中的部门信息
        const selectedDepts = value.map((id) => findById(deptOptions.value, id)).filter((dept) => dept !== null)
        selectedDept = selectedDepts.length === 1 ? selectedDepts[0] : selectedDepts
      } else if (typeof value === 'string') {
        selectedDept = findById(deptOptions.value, value)
      }
    }

    emit('change', value)
    emit('select', value, selectedDept)
    console.log('级联组件中----选中的部门信息', value, selectedDept)
  }
  // 关闭
  const handelColse = () => {
    console.log('级联组件关闭')
  }
  /** 刷新部门列表 */
  const refresh = () => {
    getDeptList()
  }

  // 暴露方法给父组件
  defineExpose({
    refresh,
  })

  // 生命周期
  onMounted(() => {
    getDeptList()
  })
</script>
